using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;

public class DataImport
{
    private TokenString headerTokens;
    private int _iLinesRead;
    private System.IO.StreamReader _srInput = null;

    public DataImport()
    {
        _iLinesRead = 0;
    }

    public void LoadData(string importFile, DataTable dtImport, string templateFile)
    {
        string                 strLine;
        int             i, iLineNumber = 0;

        try
        {
            try
            {
                _srInput = new StreamReader(importFile);
            }
            catch (System.Exception err)
            {
                throw new Exception("Missing import file " + importFile + "\n" + err.Message);
            }

            if (templateFile == null)
                // Read the header line.
                strLine = _srInput.ReadLine();
            else
            {
                StreamReader srTemplateInput;
                try
                {
                    srTemplateInput = new StreamReader(templateFile);
                }
                catch (System.Exception)
                {
                    throw new Exception("Missing template file " + templateFile);
                }
                // Read the header line.
                strLine = srTemplateInput.ReadLine();
                srTemplateInput.Close();
            }
            if (strLine == null)
                return;
            if (strLine.Trim().Length == 0)
                return;

            headerTokens = new TokenString(strLine, null, false);

            // Test the validity of the header names
            for (i = 0; i < headerTokens.TokenCount; i++)
            {
                if (headerTokens[i].ToLower() != "ignore" && !dtImport.Columns.Contains(headerTokens[i]))
                {
                    _srInput.Close();
                    throw new Exception("Unknown field header " + headerTokens[i] + " in file " + importFile);
                }
            }

            while ((strLine = _srInput.ReadLine()) != null)
            {
                _iLinesRead++;
                iLineNumber++;
                TokenString fieldTokens = new TokenString(strLine, nextLine, false);

                // Test that the data fields match the number of header fields.
                if (fieldTokens.TokenCount != headerTokens.TokenCount)
                {
                    throw new Exception("Incorrect number of fields " + fieldTokens.TokenCount.ToString() + " in line " + iLineNumber + " in file.  Expecting " + headerTokens.TokenCount.ToString() + " fields.");
                }

                // Create a new data row to hold the record.
                DataRow drNew = dtImport.NewRow();

                // Load the data from the string tokens into the DataRow
                for (i = 0; i < headerTokens.TokenCount; i++)
                {
                    if (headerTokens[i].ToLower() == "ignore")
                        continue;

                    string strFieldValue = fieldTokens[i].Trim();

                    //if (fieldTokens[26].Trim() == "ECP")
                    try
                    {
                        if (strFieldValue == "")
                            drNew[headerTokens[i]] = DBNull.Value;
                        else if (dtImport.Columns[headerTokens[i]].DataType == System.Type.GetType("System.DateTime"))
                        {
                            // If the value is blank with the exception of slashes then clear the string.
                            if (strFieldValue.Replace('/', ' ').Replace('-', ' ').Replace(':', ' ').Trim() == string.Empty)
                                drNew[headerTokens[i]] = DBNull.Value;
                            else
                                // If the data type is Date/Time then try formatting the string as a date.
                                drNew[headerTokens[i]] =
                                    System.DateTime.ParseExact(strFieldValue,
                                    new String[] { "yyyyMMdd", 
											       "M/d/yyyy", 
											       "M/d/yy", 
											       "M/d/yyh:m:stt", 
                                                   "M/d/yyH:m:s",
                                                   "M/d/yyyyH:m:s",
											       "M/d/yyyyh:m:stt",
											       "M/d/yyyyh:m",
											       "Mdyyh:m:stt",
											       "Myy",
                                                   "Myyyy"},
                                    null,
                                    System.Globalization.DateTimeStyles.AllowWhiteSpaces);
                        }
                        else if (dtImport.Columns[headerTokens[i]].DataType == System.Type.GetType("System.Int32"))
                        {
                            drNew[headerTokens[i]] = Int32.Parse(strFieldValue, System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowLeadingSign | System.Globalization.NumberStyles.AllowThousands);
                        }
                        else
                        {
                            // Remove dollar signs from the beginning of field values
                            if (strFieldValue.Trim().Length > 1)
                                if (strFieldValue.TrimStart().Substring(0, 1) == "$")
                                    strFieldValue = strFieldValue.TrimStart().Substring(1);

                            // Put the field value into the record
                            drNew[headerTokens[i]] = strFieldValue;
                        }
                    }
                    catch (System.Exception)
                    {
                        throw new Exception("Format error - field " + headerTokens[i] + ". Expecting " + dtImport.Columns[headerTokens[i]].DataType.FullName);
                    }
                }

                try {dtImport.Rows.Add(drNew);}
                catch (System.Exception err) {throw new Exception("Format error - line " + iLineNumber.ToString() + "\n" + err.Message);}
            }
        }
        finally
        {
            if (_srInput != null)
                _srInput.Close();
        }
    }

    public int LinesRead
    {
        get { return _iLinesRead; }
    }

    public string nextLine()
    {
        return _srInput.ReadLine();
    }
}
